/*
 * Copyright (C) 2006 Johan Maasing johan at zoom.nu Licensed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package nu.zoom.swing.desktop.frame;

import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JMenuBar;

import nu.zoom.swing.desktop.common.BackendException;
import nu.zoom.swing.desktop.preferences.Preferences;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

abstract class WorkbenchFrameDelegate {

    private Log log = LogFactory.getLog(getClass());
    protected final DetachableWorkbenchFrame owner;
    protected final Preferences preferences;
    protected final String preferencesKey;
    private final JComponent content;
    private final JMenuBar frameMenu;
    private final boolean resizable;
    private final boolean maximizable;
    private List<ImageIcon> icons = new ArrayList<ImageIcon>();

    public WorkbenchFrameDelegate(final DetachableWorkbenchFrame owner,
            final Preferences preferences, final String preferencesKey,
            final JComponent content, final JMenuBar frameMenu,
            final boolean resizable, final boolean maximizable) {
        this.owner = owner;
        this.preferences = preferences;
        this.preferencesKey = preferencesKey;
        this.content = content;
        this.frameMenu = frameMenu;
        this.resizable = resizable;
        this.maximizable = maximizable;
    }

    abstract void dispose();

    abstract String getTitle();

    abstract boolean isVisible();

    abstract void moveToFront();

    void setFrameIcon(List<ImageIcon> icons) {
        this.icons = icons;
        delegateSetIcons(icons);
    }

    List<ImageIcon> getFrameIcons() {
        return icons;
    }

    abstract void delegateSetIcons(List<ImageIcon> icons);

    abstract void setTitle(String newTitle);

    abstract void setVisible(boolean visible);

    abstract FrameVisualPreferences getFrameVisualPreferencesFromFrame();

    protected void savePreferences() {
        FrameVisualPreferences prefs = getFrameVisualPreferencesFromFrame();
        if (prefs != null) {
            try {
                if (log.isTraceEnabled()) {
                    log.trace("Trying to store disposing frame position and size to preferences using key: "
                            + preferencesKey);
                }
                preferences.setInteger(preferencesKey + ".width", prefs.getWidth());
                preferences.setInteger(preferencesKey + ".height", prefs.getHeight());
                preferences.setInteger(preferencesKey + ".x", prefs.getPositionx());
                preferences.setInteger(preferencesKey + ".y", prefs.getPositiony());
            } catch (BackendException e) {
                log.warn("Unable to store preferences", e);
            }
        }
    }

    FrameVisualPreferences getFrameVisualPreferencesFromPreferences() {
        try {
            Integer width = preferences.getInteger(preferencesKey + ".width");
            Integer height = preferences.getInteger(preferencesKey + ".height");
            Integer x = preferences.getInteger(preferencesKey + ".x");
            Integer y = preferences.getInteger(preferencesKey + ".y");
            return new FrameVisualPreferences(width, height, x, y);
        } catch (Exception e) {
            log.warn("Unable to retrieve frame visual preferences", e);
            return null;
        }
    }

    JComponent getContent() {
        return content;
    }

    JMenuBar getFrameMenu() {
        return frameMenu;
    }

    public synchronized boolean isMaximizable() {
        return maximizable;
    }

    public synchronized boolean isResizable() {
        return resizable;
    }

    abstract void savePreferencesAndDisposeOfNativeFrameWithoutCallbacks();
}
